#!/usr/bin/python
# -*-coding:UTF-8 -*-

# ========================
# @Time  : 2021/3/8
# @Author: Sunny
# ========================
"""
1、将python高阶内容，所学知识点整理成笔记（有时间话可以画出思维导图）
"""

"""
2、进程+协程实现并发小练习，假设一个队列中有100000个URL地址，每个请求需要0.4秒钟，尝试用4个进程，每个进程中开启5000个协程去请求
（async await或者gevent去实现）！统计运行时间
# """

from gevent import monkey

import requests
import time
from multiprocessing import Process, Queue
import gevent


# 定义装饰器
def decorator(func):
    def wrapper(*args):
        # 获取程序执行前的时间
        start = time.time()
        # 执行功能程序
        func(*args)
        # 获取程序执行后的时间
        end = time.time()
        print(f'程序的执行时间为:{end - start}')
        return end - start

    return wrapper


class MyProcess(Process):
    def __init__(self, que):
        super().__init__()
        self.que = que

    # 进程的任务是创建携程，所以run方法里面写创建协程
    def run(self):
        # 注意点：不定要打在进程之中，否则影响进程的队列模块使用
        from gevent import monkey
        monkey.patch_all()
        cor_list=[]
        # 进程的工作函数（创建协程）
        for i in range(5000):
            cor = gevent.spawn(self.cor_work,i)
            cor_list.append(cor)
        # 遍历列表，让所有的协程等待
        gevent.joinall(cor_list)

    def cor_work(self,i):
        # 协程函数的工作任务
        while self.que.qsize()>0:
            try:
                url = self.que.get(timeout=0.001)
            except:
                # print('进程中无数据')
                break
            else:
                print(f'进程：{self.pid}----第{i}个携程程正在请求{url}')
                time.sleep(1)
@decorator
def main():
    # 将url放入队列
    que = Queue()
    for i in range(100000):
        url = f'https://www.baidu.com/___{i}'
        que.put(url)

    # 创建4个进程并且启动
    p_list = []
    for i in range(4):
        p = MyProcess(que)
        p_list.append(p)
        p.start()

    # 设置等待
    for q in p_list:
        q.join()


if __name__ == '__main__':
    main()


